package com.example.tobebigfe.utils

import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import android.util.Log

/**
 * @ClassName: ShakeSensor
 * @Description: 摇一摇传感器，内部原理为加速度传感器，摇一摇到达速度阀值则出发相应的动作， 回调onShakeComplete方法
 */
class ShakeSensor
/**
 * @param context        App的context
 * @param speedShreshold 摇一摇的速度阀值，默认为2000
 * @Title: UMShakeSensor
 * @Description: UMShakeSensor Constructor
 */
@JvmOverloads constructor(context: Context, speedShreshold: Int = DEFAULT_SHAKE_SPEED) : SensorEventListener {
    /**
     * App Context
     */
    protected var mContext: Context? = null
    /**
     * 传感器管理器
     */
    protected var mSensorManager: SensorManager? = null
    /**
     * 目标传感器
     */
    /**
     * @return
     * @throws
     * @Title: getSensor
     * @Description:获取传感器
     */
    var sensor: Sensor? = null
        protected set
    /**
     * 传感器监听器, 摇一摇以后回调onShakeComplete方法
     */
    /**
     * 获取 mShakeListener
     *
     * @return 返回 mShakeListener
     */
    /**
     * 设置 mShakeListener
     *
     *
     * 对mShakeListener进行赋值
     */
    var shakeListener: OnShakeListener? = null
    /**
     * 类的tag
     */
    protected val TAG = this.javaClass.name
    /**
     * 速度阈值，当摇晃速度达到这值后产生作用
     */
    private var mSpeedShreshold = DEFAULT_SHAKE_SPEED
    /**
     * 传感器是否启动
     */
    private var isStart = false
    /**
     * 手机上一个位置时重力感应坐标
     */
    private var mLastX = 0.0f
    private var mLastY = 0.0f
    private var mLastZ = 0.0f
    /**
     * 上次检测时间
     */
    private var mLastUpdateTime: Long = 0
    /**
     * 获取摇一摇的速度阀值 mSpeedShreshold
     *
     * @return 返回 mSpeedShreshold
     */
    /**
     * 设置摇一摇的速度阀值 mSpeedShreshold
     *
     *
     * 对mSpeedShreshold进行赋值
     */
    var speedShreshold: Int
        get() = mSpeedShreshold
        set(speedShreshold) {
            var speedShreshold = speedShreshold
            if (speedShreshold < 0) {
                speedShreshold = 0
                Log.e(TAG, "speedShreshold速度阀值不能小于0，自动重置为0.")
            }
            this.mSpeedShreshold = speedShreshold
        }

    init {
        mContext = context
        mSpeedShreshold = speedShreshold
    }

    /**
     * @return boolean 注册是否成功的标识
     * @throws
     * @Title: register
     * @Description: 注册传感器，返回是否注册成功
     */
    fun register(): Boolean {
        // 获得传感器管理器
        mSensorManager = mContext!!
            .getSystemService(Context.SENSOR_SERVICE) as SensorManager
        if (mSensorManager != null) {
            // 获得重力传感器
            sensor = mSensorManager!!
                .getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        }
        // 注册传感器
        if (sensor != null) {
            isStart = mSensorManager!!.registerListener(
                this, sensor,
                SensorManager.SENSOR_DELAY_GAME
            )
        } else {
            Log.d(TAG, "### 传感器初始化失败!")
        }
        return isStart
    }

    /**
     * @throws
     * @Title: stop
     * @Description: 在传感器没有被锁住的情况下, 注销传感器，并且清理一些对象和状态
     */
    fun unregister() {
        if (mSensorManager != null) {
            mSensorManager!!.unregisterListener(this)
            isStart = false
            shakeListener = null
        }
    }

    /**
     * (非 Javadoc)
     *
     * @param sensor
     * @param accuracy
     * @Title: onAccuracyChanged
     * @Description:
     * @see android.hardware.SensorEventListener.onAccuracyChanged
     */
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        Log.d(TAG, "### onAccuracyChanged,  accuracy = $accuracy")
    }

    /**
     *
     * @param event
     * @Title: onSensorChanged
     * @Description: 重力感应器感应获得变化数据
     * @see android.hardware.SensorEventListener.onSensorChanged
     */
    override fun onSensorChanged(event: SensorEvent) {
        // 现在检测时间
        val currentUpdateTime = System.currentTimeMillis()
        // 两次检测的时间间隔
        val timeInterval = currentUpdateTime - mLastUpdateTime
        if (timeInterval < UPTATE_INTERVAL_TIME) {
            return
        }
        // 现在的时间变成last时间
        mLastUpdateTime = currentUpdateTime
        // 获得x,y,z坐标
        val x = event.values[0]
        val y = event.values[1]
        val z = event.values[2]
        // 获得x,y,z的变化值
        val deltaX = x - mLastX
        val deltaY = y - mLastY
        val deltaZ = z - mLastZ
        // 将现在的坐标变成last坐标
        mLastX = x
        mLastY = y
        mLastZ = z
        // 获取摇晃速度
        val speed =
            Math.sqrt((deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ).toDouble()) / timeInterval * 10000
        // 达到速度阀值，回调给开发者
        if (speed >= mSpeedShreshold && shakeListener != null) {
            shakeListener!!.onShakeComplete(event)
        }
    } // end of onSensorChanged

    /**
     * 用于传感器动作结束后的动作和分享完成后的动作回调
     */
    interface OnShakeListener {
        fun onShakeComplete(event: SensorEvent)
    }

    companion object {
        /**
         * 传感器检测变化的时间间隔
         */
        private val UPTATE_INTERVAL_TIME = 100
        /**
         * 默认的摇一摇传感器阀值
         */
        val DEFAULT_SHAKE_SPEED = 2000
    }
}